from blib2to3.pgen2.tokenize import group
from pygments.lexer import include
from tortoise.expressions import Q

from app.controllers.saas.buckling_give import buckling_give_controller
from app.log.log import logger
from app.controllers.saas.buckling import buckling_controller
from app.controllers.saas.buckling_group import buckling_group_controller
from app.core.crud import CRUDBase
from app.models import Goods, GoodsSku, OrdersGoods, AppointmentList, AppointmentSpace, User, OrdersList
from app.models.saas import BucklingTodo, Buckling, BucklingGroup
from app.schemas.saas import BucklingTodoCreate, BucklingTodoUpdate, BucklingCreate, BucklingSelect, \
    BucklingGroupCreate, BucklingGiveCreate
from datetime import datetime, timedelta
from tortoise.transactions import in_transaction


class BucklingTodoController(CRUDBase[BucklingTodo, BucklingTodoCreate, BucklingTodoUpdate]):
    def __init__(self):
        super().__init__(model=BucklingTodo)

    async def do_list(self, page: int, page_size: int, search: Q = Q()):
        query = self.model.filter(search)
        total = await query.count()
        objs = await query.offset((page - 1) * page_size).limit(page_size).order_by('-id')
        data = [await obj.to_dict(exclude_fields=["updated_at", "deleted_at"]) for obj in objs]
        return total, data

    async def do_list_buckling(self, page: int, page_size: int, search: Q = Q()):

        query = self.model.filter(search)
        total = await query.count()
        objs = await query.offset((page - 1) * page_size).limit(page_size).order_by('-status', '-id')
        data = [await obj.to_dict(exclude_fields=["updated_at", "deleted_at"]) for obj in objs]
        ##这里是因为只有sku没有商品信息,所以拿到所有的goods_id
        for item in data:
            ##to-do
            order_goods_data = await OrdersGoods.filter(id=item['order_goods_id']).first().values("id", "give_type",
                                                                                                  "attr", "goods_id")
            goods_data = await Goods.filter(id=order_goods_data['goods_id']).first().values("id", "cover", "name")
            item['goods_cover'] = goods_data['cover'] if goods_data else ''
            if order_goods_data["give_type"] == 1:
                item['goods_name'] = f"{goods_data['name']}(自购赠送)"
            elif order_goods_data["give_type"] == 2:
                item['goods_name'] = f"{goods_data['name']}(他购赠送)"
            else:
                item['goods_name'] = goods_data['name']
            item['groups'] = []
            if item['type'] == 1:
                ##组合包
                buckling_data_obj = await Buckling.filter(todo_id=item['id']).all()
                buckling_data = [await obj.to_dict(exclude_fields=["updated_at", "deleted_at"]) for obj in
                                 buckling_data_obj]
                group_data = []
                ##未开卡
                for buckling in buckling_data:
                    sku_data = await GoodsSku.filter(id=buckling['sku_id']).first().values("sku_name", "goods_id")
                    good_data = await Goods.filter(id=sku_data['goods_id']).first().values("name")
                    space_data = await AppointmentSpace.filter(id=buckling['space_id']).first().values("name")
                    space_name = space_data['name'] if space_data else '所有门店'
                    ##每个未开卡项目
                    a_data = {
                        'id': buckling['id'],
                        'good_name': good_data['name'],
                        'sku_name': sku_data['sku_name'],
                        'nums': buckling['nums'],
                        'direction': buckling['direction'],
                        'space_id': buckling['space_id'],
                        'space_name': space_name,
                        'use_nums': buckling['use_nums'],
                        'last_nums': buckling['last_nums'],
                        'price': buckling['price'],
                        'over_date': buckling['over_date'],
                    }
                    group_data.append(a_data)
                item['groups'].append({
                    'is_show': False,
                    'buckling_item': group_data
                })
            if item['type'] == 2:
                buckling_group_data_obj = await BucklingGroup.filter(todo_id=item['id']).all()
                buckling_group_data = [await obj.to_dict(exclude_fields=["updated_at", "deleted_at"]) for obj in
                                       buckling_group_data_obj]
                ##组合包
                for group_data in buckling_group_data:
                    buckling_data_obj = await Buckling.filter(group_id=group_data['id']).all()
                    buckling_data = [await obj.to_dict(exclude_fields=["updated_at", "deleted_at"]) for obj in
                                     buckling_data_obj]
                    group_data['buckling_item'] = []
                    group_data['is_show'] = True
                    ##未开卡
                    for buckling in buckling_data:
                        sku_data = await GoodsSku.filter(id=buckling['sku_id']).first().values("sku_name", "goods_id")
                        good_data = await Goods.filter(id=sku_data['goods_id']).first().values("name")
                        space_data = await AppointmentSpace.filter(id=buckling['space_id']).first().values("name")
                        space_name = space_data['name'] if space_data else '所有门店'
                        ##每个未开卡项目
                        a_data = {
                            'id': buckling['id'],
                            'good_name': good_data['name'],
                            'sku_name': sku_data['sku_name'],
                            'nums': buckling['nums'],
                            'direction': buckling['direction'],
                            'space_id': buckling['space_id'],
                            'space_name': space_name,
                            'use_nums': buckling['use_nums'],
                            'last_nums': buckling['last_nums'],
                            'price': buckling['price'],
                            'over_date': buckling['over_date'],
                        }
                        group_data['buckling_item'].append(a_data)
                item['groups'] = buckling_group_data
        return total, data

    async def do_detail(self, data_id: int):
        obj = await self.get(id=data_id)
        data = await obj.to_dict()
        return data

    async def do_create(self, obj_in: BucklingTodoCreate):
        await self.create(obj_in=obj_in)
        return True

    async def do_update(self, obj_in: BucklingTodoUpdate):
        await self.update(id=obj_in.id, obj_in=obj_in)
        return True

    async def do_delete(self, data_id: int):
        await self.remove(id=data_id)
        return True

    async def do_get_group(self, data_id: int):
        todo_data = await BucklingTodo.filter(id=data_id).first().values()
        type = todo_data['type']
        goods_data = await Goods.filter(id=todo_data['goods_id']).first().values()
        sku_data = await GoodsSku.filter(id=todo_data['sku_id']).first().values()
        bd_include = []
        if type == 1:
            bd_include.append({
                "id": 1,
                "name": "项目",
                "type": 0,
                "goods": [{"num": todo_data['nums'], "sku_id": todo_data['sku_id'], "sku_name": sku_data['sku_name'],
                           "goods_name": goods_data['name']}]
            })
            data = {
                "bd_include": bd_include
            }
        else:
            ##开套餐卡，选择组合
            data = sku_data["include"]
        return data

    async def do_start(self, obj_in: BucklingSelect):

        logger.info(f"进入开卡步骤todo_id:{obj_in.id}")
        now = datetime.now()
        now_date = now.strftime("%Y-%m-%d")
        todo_id = obj_in.id
        add_uid = obj_in.add_uid
        admin = await User.filter(id=add_uid).first().values()
        space_id = admin["space_id"]
        todo_data = await BucklingTodo.filter(id=todo_id).first().values()
        type = todo_data['type']

        logger.info(f"验证阶段")
        if todo_data["status"] == 1:
            return {"code": 0, "msg": f"当前卡已经完成开卡,请勿重复操作"}

        async with in_transaction() as transaction:
            if type == 1:
                sku_id = todo_data['sku_id']
                nums = todo_data['nums']
                logger.info(f"生产项目{sku_id},数量{nums}")
                buckling_in = BucklingCreate(
                    order_id=todo_data['order_id'],
                    goods_id=todo_data['goods_id'],
                    sku_id=sku_id,
                    user_id=todo_data["user_id"],
                    nums=nums,
                    direction=1,
                    add_uid=add_uid,
                    space_id=space_id,
                    use_nums=0,
                    last_nums=nums,
                    todo_id=todo_id,
                    over_date=None
                )
                await buckling_controller.do_create(obj_in=buckling_in)
            else:
                logger.info(f"生产套餐卡")
                sku_data = await GoodsSku.filter(id=todo_data['sku_id']).first().values()
                can_do = sku_data["include"]["zx_can_do"]
                sku_include = sku_data["include"]
                bd_num = 0  ##
                if sku_include:
                    if sku_include["bd_include"]:
                        ##必得组合
                        for group_item in sku_include["bd_include"]:
                            bd_num = bd_num + 1
                            ##计算超期时间
                            over_date = ""
                            if group_item['times'] > 0:
                                future_date = now + timedelta(days=group_item['times'])
                                over_date = future_date.strftime("%Y-%m-%d")
                            ##插入已选组合包表
                            group_data = BucklingGroupCreate(
                                type=1,
                                todo_id=todo_id,
                                group_id=group_item['id'],
                                group_name=group_item['name'],
                                group_type=group_item['type'],
                                times=group_item['times'],
                                use_times=0,
                                last_times=group_item['times'],
                                over_date=over_date
                            )
                            ret = await buckling_group_controller.do_create(obj_in=group_data)
                            ##插入待划扣
                            for goods in group_item["goods"]:
                                buckling_in = BucklingCreate(
                                    order_id=todo_data['order_id'],
                                    goods_id=todo_data['goods_id'],
                                    sku_id=goods['sku_id'],
                                    user_id=todo_data["user_id"],
                                    nums=goods['num'],
                                    direction=1,
                                    add_uid=add_uid,
                                    space_id=space_id,
                                    use_nums=0,
                                    last_nums=goods['num'],
                                    todo_id=todo_id,
                                    over_date=over_date,
                                    group_id=ret.id
                                )
                                await buckling_controller.do_create(obj_in=buckling_in)
                    if sku_include["zx_include"]:
                        if can_do > 0:
                            logger.info(obj_in.selected_ids)
                            if len(obj_in.selected_ids) - bd_num != can_do:
                                return {"code": 0, "msg": f"选择组合包的数量错误,应该要选择{can_do}个"}
                        ##选择组合
                        for group_item in sku_include["zx_include"]:
                            group_id = group_item['id']
                            if group_id in obj_in.selected_ids:
                                ##计算超期时间
                                over_date = ""
                                if group_item['times'] > 0:
                                    future_date = now + timedelta(days=group_item['times'])
                                    over_date = future_date.strftime("%Y-%m-%d")
                                ##插入已选组合包表
                                group_data = BucklingGroupCreate(
                                    type=2,
                                    todo_id=todo_id,
                                    group_id=group_id,
                                    group_name=group_item['name'],
                                    group_type=group_item['type'],
                                    times=group_item['times'],
                                    over_date=over_date
                                )
                                ret = await buckling_group_controller.do_create(obj_in=group_data)
                                ##插入待划扣
                                for goods in group_item["goods"]:
                                    buckling_in = BucklingCreate(
                                        order_id=todo_data['order_id'],
                                        goods_id=todo_data['goods_id'],
                                        sku_id=goods['sku_id'],
                                        user_id=todo_data["user_id"],
                                        nums=goods['num'],
                                        direction=1,
                                        add_uid=add_uid,
                                        space_id=space_id,
                                        use_nums=0,
                                        last_nums=goods['num'],
                                        todo_id=todo_id,
                                        over_date=over_date,
                                        group_id=ret.id
                                    )
                                    await buckling_controller.do_create(obj_in=buckling_in)
            await BucklingTodo.filter(id=todo_id, status=0).update(status=1, start_date=now_date, space_id=space_id)
            return {"code": 1, "msg": f"开卡成功"}

    async def do_give_todo(self, todo_id: int, new_customer_id: int, giver_customer_id: int, add_uid: int):
        try:
            # 使用事务确保订单、商品和库存更新的原子性
            async with in_transaction() as transaction:
                todo = await self.model.filter(id=todo_id).first()
                buckling_give = BucklingGiveCreate(
                    order_id=todo.order_id,
                    order_goods_id=todo.order_goods_id,
                    buckling_todo_id=todo.id,
                    new_customer_id=new_customer_id,
                    giver_customer_id=giver_customer_id,
                    add_uid=add_uid,
                )
                await buckling_give_controller.do_create(obj_in=buckling_give)
                await BucklingTodo.filter(id=todo.id).update(user_id=new_customer_id)
                await Buckling.filter(todo_id=todo_id).update(user_id=new_customer_id)
                return {"code": 1, "msg": f"转赠成功"}
        except Exception as e:
            logger.info(f"转赠过程中发生错误{todo_id}: {e}")
            return {"code": 2, "msg": f"转赠过程过程中发生错误: {e}"}

buckling_todo_controller = BucklingTodoController()
